home *** CD-ROM | disk | FTP | other *** search
/ Netscape Plug-Ins Developer's Kit / Netscape_Plug-Ins_Developers_Kit.iso / CGIPERL / MACPERL / MSRCE418.HQX / Perl Source ƒ / MacPerl / MPDrop.c < prev    next >
Encoding:
C/C++ Source or Header  |  1994-07-14  |  7.7 KB  |  361 lines

  1. /*********************************************************************
  2. Project    :    MacPerl            -    Real Perl Application
  3. File        :    MPDrop.c            -    Droplets
  4. Author    :    Matthias Neeracher
  5. Language    :    MPW C
  6.  
  7. $Log: MPDrop.c,v $
  8. Revision 1.2  1994/05/04  02:50:15  neeri
  9. Debugger support.
  10.  
  11. Revision 1.1  1994/02/27  23:00:19  neeri
  12. Initial revision
  13.  
  14. Revision 0.1  1993/10/02  00:00:00  neeri
  15. Compiles correctly
  16.  
  17. *********************************************************************/
  18.  
  19. #include <Dialogs.h>
  20. #include <QuickDraw.h>
  21. #include <Windows.h>
  22. #include <Menus.h>
  23. #include <Fonts.h>
  24. #include <AppleEvents.h>
  25. #include <AERegistry.h>
  26. #include <Processes.h>
  27. #include <files.h>
  28. #include <StandardFile.h>
  29. #include <Aliases.h>
  30. #include <GestaltEqu.h>
  31. #include <Folders.h>
  32. #include <Errors.h>
  33. #include <Resources.h>
  34.  
  35. #if !defined(powerc) && !defined(__powerc)
  36. #pragma segment Main
  37. #endif
  38.  
  39. #define FAILOSERR(call) if (err = call) return err; else 0
  40.  
  41. Boolean        gQuitting;
  42. FSSpec        gMySelf;
  43. EventRecord    gLastEvent;
  44.  
  45. pascal Boolean CheckEnvironment()
  46. {
  47.     long    result;
  48.     
  49.     if (Gestalt(gestaltAppleEventsAttr, &result))
  50.         return false;
  51.         
  52.     return (result & (1 << gestaltAppleEventsPresent)) != 0;
  53. }  /* CheckEnvironment */
  54.  
  55. /* The following stuff is adapted from Jens Peter Alfke's SignatureToApp code */
  56.  
  57. OSErr MacPerlRunning(ProcessSerialNumber *psn)
  58. {
  59.     OSErr err;
  60.     ProcessInfoRec info;
  61.     
  62.     psn->highLongOfPSN = 0;
  63.     psn->lowLongOfPSN  = kNoProcess;
  64.     do    {
  65.         FAILOSERR(GetNextProcess(psn));
  66.             
  67.         info.processInfoLength     = sizeof(info);
  68.         info.processName             = nil;
  69.         info.processAppSpec         = nil;
  70.         
  71.         FAILOSERR(GetProcessInformation(psn, &info));
  72.     } while(info.processSignature != 'McPL');
  73.  
  74.     *psn = info.processNumber;
  75.     
  76.     return noErr;
  77. }
  78.  
  79. OSErr GetSysVolume(short *vRefNum)
  80. {
  81.     long dir;
  82.     
  83.     return FindFolder(kOnSystemDisk, kSystemFolderType, false, vRefNum, &dir);
  84. }
  85.  
  86. OSErr GetIndVolume(short index, short *vRefNum)
  87. {
  88.     OSErr             err;
  89.     ParamBlockRec     pb;
  90.     
  91.     pb.volumeParam.ioNamePtr     = nil;
  92.     pb.volumeParam.ioVolIndex     = index;
  93.     
  94.     FAILOSERR(PBGetVInfoSync(&pb));
  95.     
  96.     *vRefNum = pb.volumeParam.ioVRefNum;
  97.     
  98.     return noErr;
  99. }
  100.  
  101. OSErr VolHasDesktopDB(short vRefNum, Boolean * hasDesktop)
  102. {
  103.     OSErr                         err;
  104.     HParamBlockRec             pb;
  105.     GetVolParmsInfoBuffer     info;
  106.     
  107.     pb.ioParam.ioNamePtr     = nil;
  108.     pb.ioParam.ioVRefNum     = vRefNum;
  109.     pb.ioParam.ioBuffer         = (Ptr)&info;
  110.     pb.ioParam.ioReqCount     = sizeof(GetVolParmsInfoBuffer);
  111.     
  112.     FAILOSERR(PBHGetVolParmsSync(&pb));
  113.  
  114.     *hasDesktop = (info.vMAttrib & (1 << bHasDesktopMgr))!=0;
  115.     
  116.     return noErr;
  117. }
  118.  
  119. OSErr FindAppOnVolume(short vRefNum, FSSpec *file)
  120. {
  121.     OSErr     err;
  122.     DTPBRec     pb;
  123.     
  124.     /* Get Acess path to Desktop database on this volume */
  125.     
  126.     pb.ioVRefNum         = vRefNum;
  127.     pb.ioNamePtr         = nil;
  128.     FAILOSERR(PBDTGetPath(&pb));
  129.     
  130.     pb.ioIndex             = 0;
  131.     pb.ioFileCreator     = 'McPL';
  132.     pb.ioNamePtr         = file->name;
  133.     switch (err = PBDTGetAPPLSync(&pb))    {
  134.     case noErr:
  135.         file->vRefNum     = vRefNum;
  136.         file->parID     = pb.ioAPPLParID;
  137.     
  138.         return noErr;
  139.     case fnfErr:
  140.         return afpItemNotFound;                        /* Bug in PBDTGetAPPL            */
  141.     default:
  142.         return err;
  143.     }
  144. }
  145.  
  146. OSErr LaunchIt(FSSpecPtr fileSpec, ProcessSerialNumber * psn )
  147. {
  148.     OSErr                     err;
  149.     LaunchParamBlockRec     pb;
  150.     
  151.     pb.launchBlockID             = extendedBlock;
  152.     pb.launchEPBLength         = extendedBlockLen;
  153.     pb.launchFileFlags         = launchNoFileFlags;
  154.     pb.launchControlFlags    = launchContinue + launchNoFileFlags;
  155.     pb.launchAppSpec             = fileSpec;
  156.     pb.launchAppParameters    = nil;
  157.     
  158.     FAILOSERR(LaunchApplication(&pb));
  159.  
  160.     *psn = pb.launchProcessSN;
  161.     
  162.     return noErr;
  163. }
  164.  
  165. /* Get the psn ofa copy of MacPerl. Launch one if necessary. Buy one. Steal one. */
  166. static OSErr LaunchMacPerl(ProcessSerialNumber *psn)
  167. {
  168.     OSErr     err;
  169.     short     vRefNum, sysVRefNum, index;
  170.     FSSpec     file;
  171.     Boolean     hasDesktopDB;
  172.     
  173.     /* See if ToolServer is already running:                    */
  174.     err    = MacPerlRunning(psn);
  175.     
  176.     if    (err != procNotFound)
  177.         return err;
  178.     
  179.     /* Not running, try to launch it */
  180.     
  181.     FAILOSERR(GetSysVolume(&sysVRefNum));
  182.     
  183.     vRefNum = sysVRefNum;
  184.     
  185.     for (index = 0; !err; err = GetIndVolume(++index,&vRefNum)) {
  186.         if (!index || vRefNum != sysVRefNum) {
  187.             if (err = VolHasDesktopDB(vRefNum,&hasDesktopDB))
  188.                 return err;
  189.                 
  190.             if (hasDesktopDB)    
  191.                 switch (err = FindAppOnVolume(vRefNum, &file))    {
  192.                 case noErr:
  193.                     return LaunchIt(&file, psn);
  194.                 case afpItemNotFound:
  195.                     break;
  196.                 default:
  197.                     return err;
  198.                 }
  199.         }
  200.     }
  201.     
  202.     switch (err) {
  203.     case nsvErr:
  204.     case afpItemNotFound:
  205.         return fnfErr;
  206.     default:
  207.         return err;
  208.     }
  209. }
  210.  
  211. void WhoAmI(FSSpec * me)
  212. {
  213.     FCBPBRec        fcb;
  214.     
  215.     fcb.ioNamePtr    =    &me->name;
  216.     fcb.ioRefNum    =    CurResFile();
  217.     fcb.ioFCBIndx    =    0;
  218.     
  219.     PBGetFCBInfoSync(&fcb);
  220.     
  221.     me->vRefNum    =    fcb.ioFCBVRefNum;
  222.     me->parID    =    fcb.ioFCBParID;
  223. }
  224.  
  225. pascal OSErr Yo(const AppleEvent *message, AppleEvent *reply, long refcon)
  226. {
  227.     OSErr                        err;
  228.     AppleEvent                doscript;
  229.     ProcessSerialNumber    perl;
  230.     AEAddressDesc            perladdr;
  231.     AEDescList                args;
  232.     AEDescList                incoming;
  233.     AliasHandle                alias;
  234.     AEDesc                    arg;
  235.     AEKeyword                kw;
  236.     Boolean                    doDebug = true;
  237.     
  238.     gQuitting = true;
  239.  
  240.     WaitNextEvent(0, &gLastEvent, 0, nil);
  241.     
  242.     switch (err = LaunchMacPerl(&perl)) {
  243.     case noErr:
  244.         break;
  245.     case fnfErr:
  246.         ParamText(
  247.             (StringPtr) "\pFailed to launch MacPerl. Either you don't have MacPerl "
  248.             "or your desktop needs to be rebuilt.", (StringPtr) "\p", "\p", "\p");
  249.         Alert(4096, nil);
  250.         
  251.         return err;
  252.     default:
  253.         ParamText(
  254.             (StringPtr) "\pFailed to launch MacPerl (possibly because of "
  255.             "a memory problem).", (StringPtr) "\p", "\p", "\p");
  256.         Alert(4096, nil);
  257.         
  258.         return err;
  259.     }
  260.     
  261.     FAILOSERR(SetFrontProcess(&perl));
  262.     
  263.     FAILOSERR(
  264.         AECreateDesc(
  265.             typeProcessSerialNumber,
  266.             (Ptr)&perl,
  267.             sizeof(ProcessSerialNumber),
  268.             &perladdr));
  269.     
  270.     if (refcon && (gLastEvent.modifiers & optionKey))
  271.         FAILOSERR(
  272.             AECreateAppleEvent(
  273.                 'McPL', kAEOpenDocuments, &perladdr, 
  274.                 kAutoGenerateReturnID, kAnyTransactionID, 
  275.                 &doscript));
  276.     else {
  277.         FAILOSERR(
  278.             AECreateAppleEvent(
  279.                 kAEMiscStandards, kAEDoScript, &perladdr, 
  280.                 kAutoGenerateReturnID, kAnyTransactionID, 
  281.                 &doscript));
  282.         if (gLastEvent.modifiers & controlKey)
  283.             FAILOSERR(AEPutParamPtr(&doscript, 'DEBG', typeBoolean, (Ptr) &doDebug, 1));
  284.     }
  285.     
  286.     FAILOSERR(AECreateList(nil,0,false,&args));
  287.     FAILOSERR(NewAlias(nil,&gMySelf,&alias));
  288.     
  289.     HLock((Handle) alias);
  290.     FAILOSERR(AEPutPtr(&args, 0, typeAlias, (Ptr) *alias, GetHandleSize((Handle) alias)));
  291.     DisposHandle((Handle) alias);
  292.     
  293.     if (!AEGetParamDesc(message, keyDirectObject, typeAEList, &incoming)) {
  294.         short    i = 1;
  295.         
  296.         while (!AEGetNthDesc(&incoming, i++, typeWildCard, &kw, &arg)) {
  297.             FAILOSERR(AEPutDesc(&args, 0, &arg));
  298.             AEDisposeDesc(&arg);
  299.         }
  300.         
  301.         AEDisposeDesc(&incoming);
  302.     }
  303.     
  304.     FAILOSERR(AEPutParamDesc(&doscript, keyDirectObject, &args));
  305.     FAILOSERR(
  306.         AESend(
  307.             &doscript, reply,
  308.             kAENoReply+kAEAlwaysInteract,
  309.             kAENormalPriority, kAEDefaultTimeout,
  310.             nil, nil));
  311.     
  312.     return noErr;
  313. }
  314.  
  315. pascal void MainEvent(void)
  316. {
  317.     if (WaitNextEvent(everyEvent, &gLastEvent, 60, nil))
  318.         switch (gLastEvent.what) {
  319.         case kHighLevelEvent:
  320.             AEProcessAppleEvent(&gLastEvent);
  321.             break;
  322.         }
  323. }
  324.  
  325. void main()
  326. {
  327.     InitGraf(&qd.thePort);
  328.     InitFonts();
  329.     FlushEvents(everyEvent, 0);
  330.     InitWindows();
  331.     InitMenus();
  332.     TEInit();
  333.     InitDialogs(nil);
  334.     InitCursor();
  335.  
  336.     gQuitting          = false;
  337.  
  338.     /*check environment checks to see if we are running 7.0*/
  339.     if (!CheckEnvironment()) {
  340.         SetCursor(&qd.arrow);
  341.         /*pose the only 7.0 alert*/
  342.         ParamText(
  343.             (StringPtr) "\pMacPerl droplets need at least System 7.0 to run "
  344.             "(you may run me from the \"MacPerl Runtime\" "
  345.             "application, however).", (StringPtr) "\p", "\p", "\p");
  346.         Alert(4096, nil);
  347.         
  348.         ExitToShell();
  349.     }
  350.  
  351.     /* We will not go native anytime soon */
  352.     
  353.     AEInstallEventHandler( kCoreEventClass, kAEOpenApplication, (AEEventHandlerUPP)Yo, 1, false) ;
  354.     AEInstallEventHandler( kCoreEventClass, kAEOpenDocuments,   (AEEventHandlerUPP)Yo, 0, false) ;
  355.  
  356.     WhoAmI(&gMySelf);
  357.     
  358.     while (!gQuitting)
  359.         MainEvent();
  360. }
  361.